LLVM核心库优化编译器创建的IR并将其转换为目标代码。这项艰巨的任务需要分解成一个个独立的步骤，称为“通道”(passes)。这些通道需要以正确的顺序执行，这是通道管理器的目标。

为什么不硬编码通道的顺序呢?编译器的用户通常希望编译器提供不同级别的优化。开发人员更喜欢快速的编译速度，而不是在开发期间进行优化。最终的应用程序应该运行得尽可能快，并且编译器应该能够执行复杂的优化，并且可以接受较长的编译时间。不同级别的优化需要执行不同数量的优化，所以编译器作者可能希望提供自己的通道，以利用自己对语言的了解。例如，可能希望用内联IR甚至是预先计算的结果，来替换众所周知的库函数。对于C语言，这样的通道是LLVM库的一部分，但对于其他语言，需要自行提供。了解了通道后，可能需要重新定制或添加一些通道。例如，若知道通行证的操作使一些IR代码无法访问，则希望在通道之后运行固定代码删除通道，通道管理器可以协助完成这些需求。

通道通常根据其工作的范围进行分类:

\begin{itemize}
\item
模块传递将整个模块作为输入。这样的传递在给定的模块上执行其工作，并可用于该模块内的过程内操作。

\item
调用图通道对调用图的强连接组件(scc)进行操作，自下而上的顺序遍历组件。

\item
函数通道将单个函数作为输入，并仅在该函数上执行其工作。

\item
循环通道作用于函数内部的循环。
\end{itemize}

除了IR代码之外，通道还可能需要、更新或使某些分析结果无效。执行了许多不同的分析，例如，别名分析或支配树的构造。若一个通道需要这样的分析，则可以向分析管理器请求。若已经计算了信息，将返回缓存的结果；否则，将计算该信息。若一个通道更改了IR代码，则需要宣布保留哪些分析结果，以便可以在必要时使缓存的分析信息无效。

在底层，通道管理器有以下作用:

\begin{itemize}
\item
分析结果在各通道之间共享，这需要跟踪哪个通道，需要哪个分析，以及每个分析的状态。目标是避免不必要的分析预计算，并尽快释放分析结果占用的内存。

\item
这些通道以流水线方式执行。例如，若几个函数通道应该依次执行，通道管理器将在第一个函数上运行这些函数中的每个函数，再将运行第二个函数通道的所有函数，以此类推。这里的基本思想是改进缓存行为，因为编译器只对有限的一组数据(一个IR函数)执行转换，然后切换到下一个有限的数据集。
\end{itemize}

让我们实现一个新的IR转换通道，并探索如何将其添加到优化流水线中。
















